#-*- coding:utf-8 -*-
from __future__ import unicode_literals
import urllib,urllib2,ssl,cookielib,json,time,re,datetime
from station_names import city,city2
import db_pymsql,sys#,threading
from sendmail import sendmail
ssl._create_default_https_context=ssl._create_unverified_context
tormorrow= (datetime.datetime.now()+datetime.timedelta(days=1)).strftime('%Y-%m-%d')
seat={'二等座':'O','一等座':'M','硬卧':'3','软卧':'4','硬座':'1','无座':'1'}
db=db_pymsql.db_mysql()
CLeftTicketUrl=re.findall("var CLeftTicketUrl = '(.*?)';",urllib2.urlopen('https://kyfw.12306.cn/otn/leftTicket/init').read().decode('utf-8'))[0]
print CLeftTicketUrl
class Train():
    def __init__(self,username='',password=''):
        self.username=username
        self.password=password
        self.errorCode=0
        self.count=0
        self.code_count=0
        self.n=0
        self.tmp_list=[]
        self.list2=[]
        self.c=cookielib.LWPCookieJar()
        cookie=urllib2.HTTPCookieProcessor(self.c)
        self.opener=urllib2.build_opener(cookie)
        urllib2.install_opener(self.opener)
        #self.getQurl()
        if not CLeftTicketUrl:
            self.CLeftTicketUrl='leftTicket/query'
        else:
            self.CLeftTicketUrl=CLeftTicketUrl
        self.orderlist={
        "train_date":"2017-10-25",
        "tk":"南宁东",
        "ar":"三水南",
        'choose_seats':"",
        "train_no":["K1558"],
        "passenger_name":"",
        's1':'',
        's2':'',
        'choose_wz':'',#'1F',
        'seatType':'',
        'email':'',
        'order_id':'',
        'finish_list':[],
        }
        self.getInput()
        self.orderlist['seatType']=seat.get(self.orderlist.get('choose_seats'))
        self.db=db#db_pymsql.db_mysql()
        if self.db:
            #print '数据库初始化成功'
            self.enable=True
    #1.获取网页数据checked by 2017-10-24 07:18
    def getPage(self,url,data=None,timeout=15):
        headers={'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36','Referer':'https://kyfw.12306.cn/otn/leftTicket/init',}
        req=urllib2.Request(url,data=data,headers=headers)
        h=self.opener.open(req,timeout=timeout)
        if h.getcode()==200:
            #if self.orderlist.get('order_id'):self.db.exe("update train_order set state=2,remark='获取' where order_id=%s"%self.orderlist.get('order_id'))
            return h.read()
        elif h.getcode()==302:
            self.getPage(h.geturl())
        else:
            print h.getcode()
    #2.获取主页checked by 2017-10-24 07:18
    def getQurl(self):
        h=self.getPage('https://kyfw.12306.cn/otn/leftTicket/init')
        if h:self.CLeftTicketUrl=re.findall("var CLeftTicketUrl = '(.*?)';",h)[0]
    #3.获取验证码checked by 2017-10-24 07:28
    def getCode(self):
        try:
            self.codeimg=self.getPage('https://kyfw.12306.cn/passport/captcha/captcha-image?login_site=E&module=login&rand=sjrand')
            if self.codeimg:return True
        except Exception as e:
            print '验证码下载失败'
            raise e
    #4.识别验证码#checked by 2017-10-24 07:35
    def code(self):
        if self.getCode():
            import damatuWeb
            cod=damatuWeb.codeCal(self.codeimg)
            self.code_count+=1
            print(cod)
            data={
                'answer':cod,
                'login_site':'E',
                'rand':'sjrand',
                }
            data=urllib.urlencode(data)
            h=self.getPage('https://kyfw.12306.cn/passport/captcha/captcha-check',data=data)
            h=json.loads(h)
            if h and h['result_code']=='4':
                print(h['result_message'])
                if self.count<2:
                    self.logout()
                    return self.login()
                else:
                    self.errorCode=-1
                    return '登陆次数已经到达2次!'
            elif h['result_code']==-4:
                print(h['result_message'])
                self.enable=False
                return h['result_message']
            else:
                print(h['result_message'])
                if self.code_count<5 and self.enable:
                    self.code()
        else:
            print '验证码为空,不进行识别和校验操作!'
            return '验证码为空,不进行识别和校验操作!'
    #5.登陆系统
    def login(self):
        self.login_user=''
        data={
            'username':self.username,
            'password':self.password,
            'appid':'otn',
            }
        data=urllib.urlencode(data)
        req=urllib2.Request('https://kyfw.12306.cn/passport/web/login',data=data)
        h=self.opener.open(req).read()
        self.count+=1
        h=json.loads(h)
        if h['result_code']==0:
            print(h["result_message"])
            req=urllib2.Request('https://kyfw.12306.cn/passport/web/auth/uamtk',data='appid=otn')
            print('登陆成功后获取newapptk:')
            h=self.opener.open(req).read()
            print h
            if h:
                newapptk=json.loads(h).get('newapptk')
                print '发送请求newapptk'
                req=urllib2.Request('https://kyfw.12306.cn/otn/uamauthclient',data='tk=%s'%newapptk)
                h=self.opener.open(req).read()
                if h:
                    apptk=json.loads(h).get('apptk')
                    self.login_user=json.loads(h).get('username')
                    print h
                    return True
        else:
            print(h["result_message"])
            self.errorCode=-2
            self.enable=False
            return h["result_message"]
    #获取价格
    def getPrice(self,train_no,from_station_no,to_station_no,seat_types,train_date):
        #h=self.getPage('https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no=80000D384002&from_station_no=07&to_station_no=11&seat_types=OOM&train_date=2017-11-01')
        h=self.getPage('https://kyfw.12306.cn/otn/leftTicket/queryTicketPrice?train_no={}&from_station_no={}&to_station_no={}&seat_types={}&train_date={}'.format(train_no,from_station_no,to_station_no,seat_types,train_date))
        h=json.loads(h)
        print 'train_no:',h.get('data').get('train_no')
        print '一等座: %s,二等座:%s,无座:%s'%(h.get('data').get('M'),h.get('data').get('O'),h.get('data').get('WZ'))
        print '特等座: %s,硬卧:%s,硬座:%s,软卧:%s'%(h.get('data').get('A9'),h.get('data').get('A3'),h.get('data').get('A1'),h.get('data').get('A4'))
    #获取站点明细
    def getStation(self,train_no,from_station_telecode,to_station_telecode,depart_date):
        #h=self.getPage('https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no=80000D384002&from_station_telecode=NNZ&to_station_telecode=WBZ&depart_date=2017-11-01')
        h=self.getPage('https://kyfw.12306.cn/otn/czxx/queryByTrainNo?train_no={}&from_station_telecode={}&to_station_telecode={}&depart_date={}'.format(train_no,from_station_telecode,to_station_telecode,depart_date))#tmplist[2],tmplist[6],tmplist[7],tmplist[],
        h=json.loads(h)
        for i in h.get("data").get("data"):
            if i.get('station_no')=='01':
                print i.get('station_no'),i.get('station_name'),i.get('end_station_name'),i.get('start_time'),i.get('station_train_code')#,i.get('start_station_name')
                continue
            print i.get('station_no'),i.get('station_name'),i.get('arrive_time'),i.get('start_time'),i.get('stopover_time')#,i.get('station_train_code'),i.get('start_station_name'),i.get('end_station_name')

    #6.获取用户邮箱和手机号
    def getPersonInfo(self):
        h=self.getPage('https://kyfw.12306.cn/otn/modifyUser/initQueryUserInfo','_json_att=')
        if h:
            self.email=re.findall('userDTO.email" style="display:none;" value="(.*?)" />',h)[0]
            self.bill_id=re.findall('userDTO.mobile_no" maxlength="30" style="display:none;" value="(.*?)" />',h)[0]
            print self.email,self.bill_id
            self.orderlist['email']=self.email
    #7.查找指定车次
    def findtrain(self,train_no):
        print '>>>指定的列车是:',train_no
        html=self.getTrain(self.CLeftTicketUrl,self.orderlist.get('train_date'),city[self.orderlist.get("tk")],city[self.orderlist.get("ar")])
        while not html:
            print '>>>获取不到页面信息3秒后重试'
            time.sleep(3)
            html=self.getTrain(self.CLeftTicketUrl,self.orderlist.get('train_date'),city[self.orderlist.get("tk")],city[self.orderlist.get("ar")])
        self.n+=1
        print '>>>第%s次'%self.n,time.strftime('%H:%M:%S'),'[%s]%s-%s查找车票中...'%(self.orderlist.get('train_date'),self.orderlist.get("tk"),self.orderlist.get("ar"))
        for i in html:
            self.tmp_list=i.split('|')
            if train_no:#指定车次
                if self.orderlist['choose_seats']=='二等座' and ('G' in self.tmp_list[3] or 'D' in self.tmp_list[3]):
                    if self.tmp_list[3] in train_no:print '[%s]%s 二等座:%s'%(self.n,self.tmp_list[3],self.tmp_list[30])
                    if self.tmp_list[3] in train_no and self.tmp_list[30] !='无' and self.tmp_list[30] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='一等座'  and ('G' in self.tmp_list[3] or 'D' in self.tmp_list[3]):
                    if self.tmp_list[3] in train_no:print '[%s]%s 一等座:%s'%(self.n,self.tmp_list[3],self.tmp_list[31])
                    if self.tmp_list[3] in train_no and self.tmp_list[31] !='无' and self.tmp_list[31] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='硬卧' and ('G' not in self.tmp_list[3] or 'D' not in self.tmp_list[3]):
                    if self.tmp_list[3] in train_no:print '[%s]%s 硬卧:%s'%(self.n,self.tmp_list[3],self.tmp_list[28])
                    if self.tmp_list[3] in train_no and self.tmp_list[28] !='无' and self.tmp_list[28] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='软卧' and ('G' not in self.tmp_list[3] or 'D' not in self.tmp_list[3]):
                    if self.tmp_list[3] in train_no:print '[%s]%s 软卧:%s'%(self.n,self.tmp_list[3],self.tmp_list[23])
                    if self.tmp_list[3] in train_no and self.tmp_list[23] !='无' and self.tmp_list[23] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='硬座' and ('G' not in self.tmp_list[3] or 'D' not in self.tmp_list[3]):
                    if self.tmp_list[3] in train_no:print '[%s]%s 硬座:%s'%(self.n,self.tmp_list[3],self.tmp_list[29])
                    if self.tmp_list[3] in train_no and self.tmp_list[29] !='无' and self.tmp_list[29] !='':
                        return self.printTrain()
                else:
                    #print '>>>选座条件:指定车次,座位不限!'
                    if self.tmp_list[3] in train_no:
                        if self.tmp_list[30] !='无' and self.tmp_list[30] !='':
                            print '选了二等座'
                            self.orderlist['seatType']='O'
                            return self.printTrain()
                        elif self.tmp_list[31] !='无' and self.tmp_list[31] !='':
                            print '选了一等座'
                            self.orderlist['seatType']='M'
                            return self.printTrain()
                        elif self.tmp_list[28] !='无' and self.tmp_list[28] !='':
                            print '选了硬卧'
                            self.orderlist['seatType']='3'
                            return self.printTrain()
                        elif self.tmp_list[29] !='无' and self.tmp_list[29] !='':
                            print '选了硬座'
                            self.orderlist['seatType']='1'
                            return self.printTrain()
                        elif self.tmp_list[23] !='无' and self.tmp_list[23] !='':
                            self.orderlist['seatType']='4'
                            return self.printTrain()
            else:#不指定车次
                if self.orderlist['choose_seats']=='二等座':
                    if self.tmp_list[30] !='无' and self.tmp_list[30] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='一等座':
                    if self.tmp_list[31] !='无' and self.tmp_list[31] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='硬卧':
                    if self.tmp_list[28] !='无' and self.tmp_list[28] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='软卧':
                    if self.tmp_list[23] !='无' and self.tmp_list[23] !='':
                        return self.printTrain()
                elif self.orderlist['choose_seats']=='硬座':
                    if self.tmp_list[29] !='无' and self.tmp_list[29] !='':
                        return self.printTrain()
                else:
                    print '>>>选座条件:有座位就行,座位不限'
                    if self.tmp_list[30] !='无' and self.tmp_list[30] !='':
                        print '选了二等座'
                        self.orderlist['seatType']='O'
                        return self.printTrain()
                    elif self.tmp_list[31] !='无' and self.tmp_list[31] !='':
                        print '选了一等座'
                        self.orderlist['seatType']='M'
                        return self.printTrain()
                    elif self.tmp_list[28] !='无' and self.tmp_list[28] !='':
                        print '选了硬卧'
                        self.orderlist['seatType']='3'
                        return self.printTrain()
                    elif self.tmp_list[29] !='无' and self.tmp_list[29] !='':
                        print '选了硬座'
                        self.orderlist['seatType']='1'
                        return self.printTrain()
                    elif self.tmp_list[23] !='无' and self.tmp_list[23] !='':
                        self.orderlist['seatType']='4'
                        return self.printTrain()
    #8.打印车次
    def printTrain(self):
        print '[%s]%s %s [%s-%s] 历时:%s 二等:%s 一等:%s 硬座:%s 硬卧:%s 软卧:%s 无座:%s '%(self.n,self.tmp_list[13],self.tmp_list[3],self.tmp_list[8],self.tmp_list[9],self.tmp_list[10],self.tmp_list[30],self.tmp_list[31],self.tmp_list[29],self.tmp_list[28],self.tmp_list[23],self.tmp_list[26])
        secretStr=self.tmp_list[0]
        if secretStr and self.enable:
            print '>>>查找到有票的车次,正在进入自动下单环节!'
            if self.orderlist.get('order_id'):self.db.exe("update train_order set state=11,remark='查到有车次,即将下单' where order_id=%s"%self.orderlist.get('order_id'))
            if self.order(secretStr):
                return True
        else:
            print '>>>查找不到车次,或者不在抢票时间区间!'
    #9.下单
    def order(self,secretStr):
        if self.enable:
            if self.orderlist.get("passenger_name") and (not self.orderlist.get('s1') or not self.orderlist.get('s2')):
                self.getPassInfo()#获取乘客信息
                if self.orderlist.get('order_id'):self.db.exe("update train_order set state=2,remark='获取乘客信息成功' where order_id=%s"%self.orderlist.get('order_id'))
            h=self.checkUser()
            if self.orderlist.get('order_id'):self.db.exe("update train_order set state=3,remark='检查用户信息成功' where order_id=%s"%self.orderlist.get('order_id'))
            if h and json.loads(h)['data']['flag']:
                if not self.orderlist.get("email"):
                    self.getPersonInfo()
                    self.orderlist["email"]=self.email
                h=self.submitOrderRequest(secretStr,self.orderlist.get('train_date'),self.orderlist.get('tk'),self.orderlist.get('ar'))
                if "您还有未处理的订单" in h:
                    print("有未完成订单!请先处理!")
                    print('>>>发送通知邮件!')
                    if self.getOrderState():
                        sendmail(self.orderlist["email"],'%s的%s%s-%s抢票结果'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]]),'%s订购的%s%s-%s不成功,失败原因是:有未完成订单!请先处理\n\n[%s]!!'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]],self.content))
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=99,remark='有未完成订单!请先处理' where order_id=%s"%self.orderlist.get('order_id'))
                    self.enable=False
                    return False
                rp,key_check_isChange=self.initDc()
                if self.orderlist.get('order_id'):self.db.exe("update train_order set state=4,remark='获取关键字成功' where order_id=%s"%self.orderlist.get('order_id'))
                if not self.orderlist.get('s1') or not self.orderlist.get('s1'):
                    self.getPassInfo()
                    #self.getPassenger(rp,key_check_isChange)
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=5,remark='后向获取乘客人信息成功' where order_id=%s"%self.orderlist.get('order_id'))
                if not self.checkOrderInfo(self.orderlist.get('s1'),self.orderlist.get('s2'),rp):return False
                if self.orderlist.get('order_id'):self.db.exe("update train_order set state=6,remark='检查订单信息通过' where order_id=%s"%self.orderlist.get('order_id'))
                print self.orderlist.get('seatType')
                if not self.orderlist.get('seatType'):raise
                if not self.getQueueCount(self.orderlist.get('seatType'),city.get(self.orderlist.get('tk')),city.get(self.orderlist.get('tk')),rp):
                    return False
                if self.orderlist.get('order_id'):self.db.exe("update train_order set state=7,remark='查询排队情况通过' where order_id=%s"%self.orderlist.get('order_id'))
                if self.confirmOrder(self.orderlist.get('s1'),self.orderlist.get('s2'),rp,key_check_isChange):
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=9,remark='提交订单完成' where order_id=%s"%self.orderlist.get('order_id'))
                    return True
            else:
                print '>>>没有登陆,正在重新登陆!'
                if self.code():
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=22,remark='重新登录成功' where order_id=%s"%self.orderlist.get('order_id'))
                    if self.order(secretStr):
                        return True
                else:
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=-22,remark='登录不成功!' where order_id=%s"%self.orderlist.get('order_id'))
                    #self.code()
    #10.获取查询车次
    def getTrain(self,CLeftTicketUrl,train_date,from_station,to_station):
        try:
            url='https://kyfw.12306.cn/otn/%s?leftTicketDTO.train_date=%s&leftTicketDTO.from_station=%s&leftTicketDTO.to_station=%s&purpose_codes=ADULT'%(CLeftTicketUrl,train_date,from_station,to_station)
            h=self.getPage(url).decode('utf-8')
            self.getTraindata=[]
            if '网络可能存在问题' not in h:
                h=json.loads(h)
                if h['httpstatus']==200:
                    for i in h['data']['result']:
                        t=i.split("|")
                        if '列车' in t[1]:continue
                        t[6]=city2.get(i.split("|")[6])
                        t[7]=city2.get(i.split("|")[7])
                        self.getTraindata.append(t)
                    return h['data']['result']
            else:
                print('网络可能存在问题,3秒后重试!')
                return False
        except Exception as e:
            print '获取查询车次失败!'
    #11.处理乘客信息
    def dealInfo(self,a):
        if seat.get(self.orderlist.get('choose_seats')):
            self.orderlist['seatType']=seat.get(self.orderlist.get('choose_seats'))
            print '从orderlist.choose_seats获取seatType'

        a=a.replace("'",'"')
        b=a.split(',{')
        n=0
        list1=[]
        self.list2=[]
        s=''
        for i in a:
            if i!='}':
                s+=i
            else:
                s+=i
                list1.append(s)
                s=''
        for i in list1:
            i=i.replace(',{','{')
            i=i.replace("'",'"')
            k=json.loads(i)
            self.list2.append((n,k['passenger_name'],k['passenger_id_no'],k['mobile_no']))
            print n,k['passenger_name'],k['passenger_id_no'],k['mobile_no']
            n+=1
            if not self.orderlist.get('seatType'):continue
            if self.orderlist.get("passenger_name"):
                if ',' in self.orderlist.get("passenger_name"):
                    for j in self.orderlist.get("passenger_name").split(','):
                        if j==k['passenger_name']:
                            self.orderlist['s1']+='%s,0,1,%s,1,%s,%s,N_'%(self.orderlist.get('seatType'),k['passenger_name'],k['passenger_id_no'],k['mobile_no'])
                            self.orderlist['s2']+='%s,1,%s,1_'%(k['passenger_name'],k['passenger_id_no'])
                else:
                    if self.orderlist.get("passenger_name")==k['passenger_name']:
                            self.orderlist['s1']+='%s,0,1,%s,1,%s,%s,N_'%(self.orderlist.get('seatType'),k['passenger_name'],k['passenger_id_no'],k['mobile_no'])
                            self.orderlist['s2']+='%s,1,%s,1_'%(k['passenger_name'],k['passenger_id_no'])
        print self.orderlist.get('s1'),self.orderlist.get('s2')
        if self.orderlist.get('s1') and self.orderlist['s2']:
            return True
        else:
            print ">>>self.orderlist.get('s1'),self.orderlist.get('s2')为空,编码失败"
            #self.enable=False
            #self.code_count=-5
            #return False
    #12.我的乘车人获取乘客信息
    def getPassInfo(self):
        h=self.getPage('https://kyfw.12306.cn/otn/passengers/init').decode('utf-8')
        if 'var passengers=[' in h:
            print '>>>从我的乘车人获取乘客信息!'
            p=h.split('var passengers=[')[1].split('];')[0]
            self.dealInfo(p)
            return True
        elif 'globalRepeatSubmitToken = null' in h:
            print '>>>重新登陆中!!!'
            if self.enable:
                if self.code():self.getPassInfo()
            else:
                return False
    #13.检查用户
    def checkUser(self):
        print '>>>执行checkUser检查用户状态是否有效!'
        h=self.getPage('https://kyfw.12306.cn/otn/login/checkUser',data='_json_att=')
        print h
        return h
    #14.提交订单请求
    def submitOrderRequest(self,secretStr,train_date,tk,ar):
        print '>>>有票进入预定界面'
        import sys
        reload(sys)
        sys.setdefaultencoding('utf8')
        data='secretStr=%s&train_date=%s&back_train_date=%s&tour_flag=dc&purpose_codes=ADULT&query_from_station_name=%s&query_to_station_name=%s&undefined'%(secretStr,self.orderlist.get('train_date'),time.strftime('%Y-%m-%d'),tk,ar)
        h=self.getPage('https://kyfw.12306.cn/otn/leftTicket/submitOrderRequest',data=data)
        if 'globalRepeatSubmitToken = null' in h:
            print '>>>登陆已失效,重新登陆中'
            self.code()
            self.submitOrderRequest(secretStr,self.orderlist.get('train_date'),self.orderlist.get('tk'),self.orderlist.get('ar'))
            return h
        else:
            return h
    #15.初始化参数
    def initDc(self):
        try:
            print '>>>初始化2个参数'
            h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/initDc',data='_json_att=')
            #print h
            rp=re.findall("var globalRepeatSubmitToken = '(.*?)'",h)[0]
            key_check_isChange = re.findall(r"key_check_isChange':'(.*?)'",h)[0]
            if rp or key_check_isChange:
                return rp,key_check_isChange
            else:
                print '>>>初始化2个参数initDc调用时候,获取不到rp,或者key_check_isChange参数!'
                self.errorCode=-3
        except:
            self.errorCode=-4
            print '>>>初始化2个参数initDc调用异常'
            self.initDc()
    #16.提交订单前获取乘客信息
    def getPassenger(self,rp,key_check_isChange):
        try:
            data = {
                    '_json_att':'',
                    'REPEAT_SUBMIT_TOKEN':rp
                }
            data = urllib.urlencode(data)
            h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/getPassengerDTOs',data=data)
            h=json.loads(h)
            print '>>>获取乘客信息以供选择:'
            n=0
            for k in h["data"]["normal_passengers"]:
                print n,k['passenger_name'],k['passenger_id_no'],k['mobile_no']
                n+=1
            print '>>>获取乘客信息'#下单环节3
            num=raw_input('请选择乘客(0~8),多个乘客请输入(0,1):')
            num=num.split(',')
            for i in num:
                self.orderlist['s1']+='%s,0,1,%s,1,%s,%s,N_'%(self.orderlist.get('seatType'),h["data"]["normal_passengers"][int(i)]["passenger_name"],h["data"]["normal_passengers"][int(i)]["passenger_id_no"],h["data"]["normal_passengers"][int(i)]["mobile_no"])
                self.orderlist['s2']+='%s,1,%s,1_'%(h["data"]["normal_passengers"][int(i)]["passenger_name"],h["data"]["normal_passengers"][int(i)]["passenger_id_no"])
            return self.orderlist.get('s1'),self.orderlist.get('s2')
        except Exception as e:
            print '调用getPassenger异常'
    #17.校验订单信息
    def checkOrderInfo(self,s1,s2,rp):
        print '>>>检查订单信息'
        data = {
            'cancel_flag':'2',
            'bed_level_order_num':'000000000000000000000000000000',
            'passengerTicketStr':self.orderlist.get('s1').encode('utf-8'),
            'oldPassengerStr':self.orderlist.get('s2').encode('utf-8'),
            'tour_flag':'dc',
            'randCode':'',
            '_json_att':'',
            'REPEAT_SUBMIT_TOKEN':rp
        }
        data=urllib.urlencode(data)
        h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/checkOrderInfo',data=data)
        h=json.loads(h)
        if h.get('data').get('submitStatus'):
            print '确认订单信息:',h
            if h.get('data').get('canChooseSeats')=='Y':
                print '本次列车可以选座,正在选位置:',self.orderlist.get('choose_wz')
            else:
                print '本次列车不可选座!'
                self.orderlist['choose_wz']=''
            return True
        else:
            print h.get('data').get('errMsg')
            return False
    #18.获取排队队列数量
    def getQueueCount(self,seatType,from_station,to_station,rp):
        print '>>>查询当前剩余的票数:'
        data={
            'train_date':'Thu Oct 14 2017 00:00:00 GMT+0800 (中国标准时间)'.encode('utf-8'),
            'train_no':self.tmp_list[2],
            'stationTrainCode':self.tmp_list[3],
            'seatType':self.orderlist.get('seatType'),
            'fromStationTelecode':city.get(self.orderlist.get('tk')),
            'toStationTelecode':city.get(self.orderlist.get('ar')),
            'leftTicket':self.tmp_list[12],
            'purpose_codes':'00',
            'train_location':self.tmp_list[15],
            '_json_att':'',
            'REPEAT_SUBMIT_TOKEN':rp,
        }
        data=urllib.urlencode(data)
        h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/getQueueCount',data=data)
        h=json.loads(h)
        if h.get('data'):
            print h
            return True
        else:
            print h
            return False

    #19.确认订单
    def confirmOrder(self,s1,s2,rp,key_check_isChange):
            print '>>>准备提交订单!'
            data = {
                'passengerTicketStr':self.orderlist.get('s1').encode('utf-8'),
                'oldPassengerStr':self.orderlist.get('s2').encode('utf-8'),
                'randCode':'',
                'purpose_codes':'00',
                'key_check_isChange':key_check_isChange,
                'leftTicketStr':self.tmp_list[12],
                'train_location':self.tmp_list[15],
                'choose_seats':self.orderlist.get('choose_wz'),#1F
                'seatDetailType':'000',
                'roomType':'00',
                'dwAll':'N',
                '_json_att':'',
                'REPEAT_SUBMIT_TOKEN':rp
            }
            data=urllib.urlencode(data)
            h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/confirmSingleForQueue',data=data)
            if h:
                #print h
                if json.loads(h)["data"]["submitStatus"]:
                    print('>>>车票自动提交成功\n',json.loads(h)["data"]["submitStatus"])
                    print('>>>正在获取订单结果!')
                    self.getResult(rp)
                    self.enable=False
                    return True
                else:
                    print('>>>下单不成功,错误提示是:\n',json.loads(h)["data"]["errMsg"])
                    if json.loads(h)["data"]["errMsg"]=="验证码输入错误！":
                        pass
                        #self.code()
                    return False
            else:
                print('>>>自动提交请求返回的响应为空!')
    #20.获取结果
    def getResult(self,rp):
        h=self.getPage('https://kyfw.12306.cn/otn/confirmPassenger/queryOrderWaitTime?random=%s&tourFlag=dc&_json_att=&REPEAT_SUBMIT_TOKEN=%s'%(int(time.time()),rp))
        h=json.loads(h)
        if h['data'].get('msg'):
            print(h['data']['msg'])
            if '对不起' in h['data']['msg']:
                print('>>>发送通知邮件!')
                sendmail(self.orderlist["email"],'%的%s%s-%s抢票结果'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]]),'%s订购的%s%s-%s不成功,失败原因是:%s!'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]],h['data']['msg']))
                if self.orderlist.get('order_id'):self.db.exe("update train_order set state=-8,remark='%s' where order_id=%s"%(self.orderlist.get('order_id'),h['data']['msg']))
                return False
            elif '当前提交订单用户过多' in h['data']['msg']:
                self.findtrain(self.orderlist.get('train_no'))
                time.sleep(3)
                #self.count=0
                return self.getResult(rp)
            else:
                print('>>>发送通知邮件!')
                if self.getOrderState():
                    sendmail(self.orderlist["email"],'%s订购%s%s-%s订单结果%s前支付有效'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]],self.orderlist['finish_list'][0][16]),'%s订购的%s-%s,时间%s-%s,历时%s车次为%s的车票已经于%s抢票成功,请在%s前支付!订单明细如下:\n\n[%s]'%(self.login_user,city2[self.tmp_list[6]],city2[self.tmp_list[7]],self.tmp_list[8],self.tmp_list[9],self.tmp_list[10],self.tmp_list[3],time.strftime('%Y-%m-%d %H:%M:%S'),self.orderlist['finish_list'][0][16],self.content))
                return True
        else:
            if self.count<6:
                print('>>>未获取到结果,3秒后再试!')
                self.count+=1
                time.sleep(2)
                return  self.getResult(rp)
            else:
                print('>>>获取结果超时!默认订单成功!请尽快登陆12306完成支付!')
                print('>>>发送通知邮件!')
                if self.getOrderState():
                    sendmail(self.orderlist["email"],'%s订购%s%s-%s订单结果%s前支付有效'%(self.login_user,self.orderlist.get('train_date'),city2[self.tmp_list[6]],city2[self.tmp_list[7]],self.orderlist['finish_list'][0][16]),'%s订购的%s-%s,时间%s-%s,历时%s车次为%s的车票已经于%s抢票成功,请在%s前支付!订单明细如下:\n\n[%s]'%(self.login_user,city2[self.tmp_list[6]],city2[self.tmp_list[7]],self.tmp_list[8],self.tmp_list[9],self.tmp_list[10],self.tmp_list[3],time.strftime('%Y-%m-%d %H:%M:%S'),self.orderlist['finish_list'][0][16],self.content))
                    if self.orderlist.get('order_id'):self.db.exe("update train_order set state=8,remark='发送成功邮件' where order_id=%s"%self.orderlist.get('order_id'))
                return True
    #21.交互式查询车次
    def searchTrain(self):
        print('>>>欢迎进入自动购票系统! [By侠仔](%s)'%time.strftime('%Y-%m-%d %H:%M:%S'))
        self.orderlist["tk"]=raw_input(">>>请输入出发站名:").decode('utf-8')
        while not city.get(self.orderlist.get("tk")):
            print('>>>出发站名无效,请重新输入!')
            self.orderlist["tk"]=raw_input(">>>请输入出发站名:").decode('utf-8')
        self.orderlist["ar"]=raw_input(">>>请输入到达站名:").decode('utf-8')
        while not city.get(self.orderlist.get("ar")):
            print('>>>到达站名无效,请重新输入!')
            self.orderlist["ar"]=raw_input(">>>请输入到达站名:").decode('utf-8')
        train_date=raw_input(">>>请选择日期,默认是今天!(%s):"%time.strftime('%Y-%m-%d')).decode('utf-8')
        if not train_date:
            self.orderlist["train_date"]=time.strftime('%Y-%m-%d')
        else:
            self.orderlist["train_date"]=train_date
        print('>>>正在查询%s,%s-%s的车次!'%(self.orderlist.get('train_date'),self.orderlist.get('tk'),self.orderlist.get('ar')))
        html=self.getTrain(self.CLeftTicketUrl,self.orderlist.get('train_date'),city.get(self.orderlist.get("tk")),city.get(self.orderlist.get("ar")))
        while not html:
            time.sleep(3)
            html=self.getTrain(self.CLeftTicketUrl,self.orderlist.get('train_date'),city.get(self.orderlist.get("tk")),city.get(self.orderlist.get("ar")))
        n=0
        list2=[]
        for i in html:
            tmp_list=i.split('|')
            if '列车' in tmp_list[1]:continue
            list2.append((n,tmp_list[13],tmp_list[3],city2[tmp_list[6]],city2[tmp_list[7]],tmp_list[8],tmp_list[9],tmp_list[10],tmp_list[30],tmp_list[31],tmp_list[29],tmp_list[28],tmp_list[23],tmp_list[26]))
            print('[%s]%s %s (%s-%s) [%s-%s] 历时:%s 二等:%s 一等:%s 硬座:%s 硬卧:%s 软卧:%s 无座:%s '%(n,tmp_list[13],tmp_list[3],city2[tmp_list[6]],city2[tmp_list[7]],tmp_list[8],tmp_list[9],tmp_list[10],tmp_list[30],tmp_list[31],tmp_list[29],tmp_list[28],tmp_list[23],tmp_list[26]))
            n+=1
        No=raw_input(">>>请选择车次对应的序号,多个车次请使用,隔开:").decode('utf-8')
        if ',' in No:
            for x in No.split(','):
                self.orderlist["train_no"].append(list2[int(x)][2])
        else:
            self.orderlist["train_no"]=list2[int(No)][2]
        ss={'0':'二等座','1':'一等座','2':'硬卧','3':'硬座','4':'软卧'}
        #self.getPrice(tmp_list[2],tmp_list[16],tmp_list[17],tmp_list[35],self.orderlist["train_date"])
        self.orderlist["choose_seats"]=ss.get(raw_input("请选择坐席,不选默认任意座位(二等座0,一等座1,硬卧2,硬座3,软卧4):"))
        print '>>>您选择的坐席是:',self.orderlist["choose_seats"]
        print('>>>您已选择了车次席别,请登录后选择乘车人!\n')
        self.username=raw_input(">>>请输入12306账号:")
        self.password=raw_input(">>>请输入12306密码:")
        self.getPassInfo()
        list2=self.list2
        if not list2:
            print 'search函数getPassInfo调用返回空值'
            return False
        No=raw_input(">>>请选择乘车人序号,多个乘车人,请使用,隔开:").decode('utf-8')
        while not No:
            print('>>>不能不选乘车人')
            No=raw_input(">>>请选择乘车人序号,多个乘车人,请使用,隔开:").decode('utf-8')
        if No:self.orderlist["passenger_name"]=''
        if ',' in No:
            for x in No.split(','):
                self.orderlist["passenger_name"]+=list2[int(x)][1]+','
                if self.orderlist["choose_seats"]:
                    self.orderlist["s1"]+='%s,0,1,%s,1,%s,%s,N_'%(seat.get(self.orderlist["choose_seats"]),list2[int(x)][1],list2[int(x)][2],list2[int(x)][3])
                    self.orderlist["s2"]+='%s,1,%s,1_'%(list2[int(x)][1],list2[int(x)][2])
            self.orderlist["passenger_name"]=self.orderlist["passenger_name"][:-1]
        else:
            self.orderlist["passenger_name"]+=list2[int(No)][1]
            if self.orderlist["choose_seats"]:
                self.orderlist["s1"]+='%s,0,1,%s,1,%s,%s,N_'%(seat.get(self.orderlist["choose_seats"]),list2[int(No)][1],list2[int(No)][2],list2[int(No)][3])
                self.orderlist["s2"]+='%s,1,%s,1_'%(list2[int(No)][1],list2[int(No)][2])
        self.orderlist["choose_wz"]=raw_input(">>>如果该车次能选座,请输入要选座的位置[1A(靠窗),1B,1C,1E,1F(靠窗)]:")
        self.orderlist["email"]=raw_input(">>>请输入抢票成功后通知的邮箱:")
        if not self.orderlist["email"]:self.orderlist["email"]='260760495@qq.com'
        print('>>>您选择的邮箱是:'+self.orderlist["email"])
        self.run()
    #23.是否在抢票时间段
    @property
    def istraintime(self):
        if time.strftime('%H:%M:%S')>'06:00:00' and time.strftime('%H:%M:%S')<'23:00:00':
            return True
    #24.执行
    def run(self):
        if self.orderlist.get('order_id'):self.db.exe("update train_order set state=1,remark='开始调度工单' where order_id=%s"%(self.orderlist.get('order_id')))
        while self.enable:
            if self.istraintime:
                #print '>>>当前时间在抢票时间区间,可以抢票!'
                try:
                    if self.findtrain(self.orderlist["train_no"]):break
                except Exception as e:
                    print 'findtrain调用抛异常:',e
                    #pass
                time.sleep(2)
            else:
                print('>>>{}当前时间不再抢票区间'.format(time.strftime('%Y-%m-%d %H:%M:%S')))
                time.sleep(60)
    #25.自动执行
    def autorun(self):
        # result=db_pymsql.db_mysql().exe("select * from train_order where state=0",0,True)
        if result:
            self.enable=True
            self.username=result[0].get('username')
            self.password=result[0].get('password')
            self.orderlist['train_no']=result[0].get('train_no')
            self.orderlist['choose_seats']=result[0].get('seat')
            self.orderlist['ar']=result[0].get('arrive_station')
            self.orderlist['passenger_name']=result[0].get('passenger')
            self.orderlist['tk']=result[0].get('start_station')
            self.orderlist['order_id']=result[0].get('order_id')
            self.orderlist['train_date']=result[0].get('train_date')
            if self.enable:
                self.run()
    #获取外部输入
    def getInput(self):
        if len(sys.argv)>1:
            k=0
            for i in sys.argv:
                if i=='-u':
                    self.username=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-p':
                    self.password=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-tk':
                    self.orderlist['tk']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-ar':
                    self.orderlist['ar']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-d':
                    self.orderlist['train_date']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-o':
                    self.orderlist['order_id']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-ps':
                    self.orderlist['passenger_name']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-n':
                    self.orderlist['train_no']=sys.argv[k+1]
                    k+=1
                    continue
                elif i=='-s':
                    self.orderlist['choose_seats']=sys.argv[k+1]
                    k+=1
                    continue
                k+=1
    def getOrderState(self):
        h=self.getPage('https://kyfw.12306.cn/otn/queryOrder/queryMyOrderNoComplete','_json_att=').decode('utf-8')
        if 'orderDBList' in h:
            h=json.loads(h)
            for i in range(h["data"]["orderDBList"][0]["ticket_totalnum"]):
                    array_passser_name_page=h['data']['orderDBList'][0]['array_passser_name_page'][i]
                    from_station_name_page=h['data']['orderDBList'][0]['from_station_name_page'][0]
                    order_date=h['data']['orderDBList'][0]['order_date']
                    sequence_no=h['data']['orderDBList'][0]['sequence_no']
                    start_time_page=h['data']['orderDBList'][0]['start_time_page']
                    start_train_date_page=h['data']['orderDBList'][0]['start_train_date_page']
                    ticket_price_all=h['data']['orderDBList'][0]['ticket_price_all']
                    to_station_name_page=h['data']['orderDBList'][0]['to_station_name_page'][0]
                    train_code_page=h['data']['orderDBList'][0]['train_code_page']
                    coach_no=h['data']['orderDBList'][0]['tickets'][i]['coach_no']
                    confirm_flag=h['data']['orderDBList'][0]['tickets'][i]['confirm_flag']
                    coach_no=h['data']['orderDBList'][0]['tickets'][i]['coach_no']
                    passenger_id_no=h['data']['orderDBList'][0]['tickets'][i]['passengerDTO']['passenger_id_no']
                    passenger_id_type_name=h['data']['orderDBList'][0]['tickets'][i]['passengerDTO']['passenger_id_type_name']
                    passenger_name=h['data']['orderDBList'][0]['tickets'][i]['passengerDTO']['passenger_name']
                    pay_limit_time=h['data']['orderDBList'][0]['tickets'][i]['pay_limit_time']
                    seat_name=h['data']['orderDBList'][0]['tickets'][i]['seat_name']
                    seat_type_name=h['data']['orderDBList'][0]['tickets'][i]['seat_type_name']
                    ticket_price=h['data']['orderDBList'][0]['tickets'][i]['ticket_price']
                    print array_passser_name_page,from_station_name_page,order_date,sequence_no,start_time_page,start_train_date_page,ticket_price_all,to_station_name_page,train_code_page,coach_no,confirm_flag,coach_no,passenger_id_no,passenger_id_type_name,passenger_name,passenger_id_no,pay_limit_time,seat_name,seat_type_name,float(ticket_price)/100
                    self.orderlist['finish_list'].append((array_passser_name_page,from_station_name_page,order_date,sequence_no,start_time_page,start_train_date_page,ticket_price_all,to_station_name_page,train_code_page,coach_no,confirm_flag,coach_no,passenger_id_no,passenger_id_type_name,passenger_name,passenger_id_no,pay_limit_time,seat_name,seat_type_name,float(ticket_price)/100))
            self.content=''
            n=1
            for i in self.orderlist['finish_list']:
                self.content+=u'%s,%s开 %s %s-%s %s车厢 %s %s %s %s;\n'%(n,i[5],i[8],i[1],i[7],i[11],i[17],i[18],i[14],i[19])
                n+=1
            return True
           #  '''
           # 0 尹航
           # 1 南宁东
           # 2 2017-10-27 10:27:05
           # 3 E013626488
           # 4 08:02
           # 5 2017-10-29 08:02
           # 6 97400.0
           # 7 深圳北
           # 8 G2911
           # 9 12
           # 10 N
           # 11 12
           # 12 370982199107101011
           # 13 二代身份证
           # 14 尹航
           # 15 370982199107101011
           # 16 2017-10-27 10:57:05
           # 17 03D号
           # 18 二等座
           # 19 243.5
           # '''
            #msg='%s订购的%s %s开(%s-%s)车次为%s,车厢%s,坐位%s%s,价格%s'%(self.login_user,self.orderlist.get('finish_list')[0][2],self.orderlist.get('finish_list')[0][3],)
    def logout(self):
        h=self.getPage('https://kyfw.12306.cn/otn/login/loginOut')
        #print h

if __name__=='__main__':
    train=Train()
    #train.getPrice()
    #train.getStation()
    #train.code()
    # train.getOrderState()
    #train.code()
    #train.getPersonInfo()
    #train.code()
    #train.searchTrain()
    while 1:
        result=db_pymsql.db_mysql().exe("select * from train_order where state=0",0,False)
        if result:Train().autorun()
        print time.strftime('%Y-%m-%d %H:%M:%S'),' 无单,沉默5秒!'
        time.sleep(5)


